package com.whfp.afs330h_sdk.utils;

import android.util.Log;

import com.clj.fastble.utils.HexUtil;

/**
 * 十六进制工具类
 */
public class RxHexTool {

    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};


    /**
     * 数据字符串右边自动补位
     *
     * @param str 要补位的字符串
     * @param j   补位到什么长度(字节长度)
     * @return
     */
    public static String rightFillMethod(String str, int j) {
        if (j < str.length() / 2) {
            return str;
        }
        for (int i = (str.length() / 2); i < j; i++) {
            str += "00";
        }
        return str;
    }

    /**
     * BLE数据 自动补位求和加上校验位
     *
     * @return
     */
    public static String rightFillMethodSumBleData(String str) {
        String s = rightFillMethod(str, 19);
        str = s + makeCheckSum(s);
        return str;
    }

    /**
     * 计算校验位 ，返回十六进制校验位
     */
    public static String makeCheckSum(String data) {
        //为空便返回空字符串
        if (data == null || data.length() <= 0) {
            return "";
        }
        if (data.contains(" ")) {
            data = data.replace(" ", "");//去掉空格
        }

        int dSum = 0;
        int length = data.length();
        int index = 0;
        // 遍历十六进制，并计算总和
        while (index < length) {
            String s = data.substring(index, index + 2); // 截取2位字符
            dSum += Integer.parseInt(s, 16); // 十六进制转成十进制 , 并计算十进制的总和
            index = index + 2;
        }

        int mod = dSum % 256; // 用256取余，十六进制最大是FF，FF的十进制是255
        String checkSumHex = Integer.toHexString(mod); // 余数转成十六进制
        length = checkSumHex.length();
        if (length < 2) {
            checkSumHex = "0" + checkSumHex;  // 校验位不足两位的，在前面补0
        }
        return checkSumHex;
    }

    /**
     * 十进制数转十六进制数
     *
     * @param n
     * @return
     */
    public static String intToHex(int n) {
        StringBuffer s = new StringBuffer();
        String a;
        char[] b = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        while (n != 0) {
            s = s.append(b[n % 16]);
            n = n / 16;
        }
        a = s.reverse().toString();
        return a;
    }


    /**
     * 字符串转换成为16进制(无需Unicode编码)
     *
     * @param str
     * @return
     */
    public static String str2HexStr(String str) {
        char[] chars = "0123456789ABCDEF".toCharArray();
        StringBuilder sb = new StringBuilder("");
        byte[] bs = str.getBytes();
        int bit;
        for (int i = 0; i < bs.length; i++) {
            bit = (bs[i] & 0x0f0) >> 4;
            sb.append(chars[bit]);
            bit = bs[i] & 0x0f;
            sb.append(chars[bit]);
            // sb.append(' ');
        }
        return sb.toString().trim();
    }

    /**
     * 16进制转换成为string类型字符串
     *
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.trim().equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * 计算16进制占了多少个字节长度
     *
     * @param hexString
     * @return
     */
    public static int hexStringBitNumbre(String hexString) {
        //为空直接返回0
        if (hexString == null || hexString.trim().length() <= 0) {
            return 0;
        }
        //有空格就去掉空格
        if (hexString.contains(" ")) {
            hexString = hexString.replace(" ", "");//去掉空格
        }
        return hexString.length() / 2;
    }


    /**
     * byte[]转String
     *
     * @param data     要转的数据
     * @param addSpace 字节之间是否增加空格
     * @return
     */
    public static String formatHexString(byte[] data, boolean addSpace) {
        if (data == null || data.length < 1)
            return null;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            String hex = Integer.toHexString(data[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex);
            if (addSpace)
                sb.append(" ");
        }
        return sb.toString().trim();
    }

    /**
     * byte[]转String
     *
     * @param data 要转的数据
     * @return
     */
    public static String formatHexString(byte[] data) {
        return formatHexString(data, false);
    }

    /**
     * String转byte[]
     *
     * @param hexString 要转的数据
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.trim();
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }


    /**
     * byte[]转char[]
     *
     * @param data        要转的数据
     * @param toLowerCase 字母是否转为大写
     * @return
     */
    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }

    /**
     * byte[]转char[]
     *
     * @param data 要转的数据
     * @return
     */
    public static char[] encodeHex(byte[] data) {
        return encodeHex(data, true);
    }


    protected static char[] encodeHex(byte[] data, char[] toDigits) {
        if (data == null)
            return null;
        int l = data.length;
        char[] out = new char[l << 1];
        for (int i = 0, j = 0; i < l; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
        return out;
    }


    /**
     * 十六进制转10进制
     *
     * @param: [hex]
     * @return: int
     * @description: 按位计算，位值乘权重
     */
    public static int hexToDecimal(String hex) {
        int outcome = 0;
        for (int i = 0; i < hex.length(); i++) {
            char hexChar = hex.charAt(i);
            outcome = outcome * 16 + charToDecimal(hexChar);
        }
        return outcome;
    }

    /**
     * @param: [c]
     * @return: int
     * @description:将字符转化为数字
     */
    public static int charToDecimal(char c) {
        if (c >= 'A' && c <= 'F')
            return 10 + c - 'A';
        else
            return c - '0';
    }

    public static String encodeHexStr(byte[] data) {
        return encodeHexStr(data, true);
    }

    public static String encodeHexStr(byte[] data, boolean toLowerCase) {
        return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
    }


    protected static String encodeHexStr(byte[] data, char[] toDigits) {
        return new String(encodeHex(data, toDigits));
    }


    public static byte[] decodeHex(char[] data) {

        int len = data.length;

        if ((len & 0x01) != 0) {
            throw new RuntimeException("Odd number of characters.");
        }

        byte[] out = new byte[len >> 1];

        // two characters form the hex value.
        for (int i = 0, j = 0; j < len; i++) {
            int f = toDigit(data[j], j) << 4;
            j++;
            f = f | toDigit(data[j], j);
            j++;
            out[i] = (byte) (f & 0xFF);
        }

        return out;
    }


    protected static int toDigit(char ch, int index) {
        int digit = Character.digit(ch, 16);
        if (digit == -1) {
            throw new RuntimeException("Illegal hexadecimal character " + ch
                    + " at index " + index);
        }
        return digit;
    }

    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static String extractData(byte[] data, int position) {
        return HexUtil.formatHexString(new byte[]{data[position]});
    }


    /**
     * 二进制转换为十进制
     *
     * @param bin 2进制表示字符串
     * @return
     */
    public static String binToHex(String bin) {
        //把2进制字符串key，转成10进制keys
        int keys = Integer.parseInt(bin, 2);//数字2代表进制，可以是各种进制，转换成10进制
        Log.i("转换成10进制：", keys + "");
        //把10进制keys转成16进制result，toUpperCase()是把小写字母转换成大写字母
        String result = Integer.toHexString(keys).toUpperCase();
        return result;
    }


    /**
     * 判断wzx数据是否正常
     */
    public static boolean isWxzData(String data) {
        return data.length() / 2 == 20 && data.substring(38, 40).equals(RxHexTool.makeCheckSum(data.substring(0, data.length() - 2)));
    }
}
